package com.lboyang.remoting.serialize.protostuff;


import com.lboyang.remoting.serialize.Serializer;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

/**
 * @Description:
 *      Protostuff 序列化
 * @Date 2021/9/11 20:58
 * @author: A.iguodala
 */
public class ProtostuffSerializer implements Serializer {



    /**
     * 使用一个缓存用户空间避免每次都重新开辟
     */
    private static final LinkedBuffer BUFFER = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);

    /**
     * 序列化方法
     *
     * @param obj 要序列化的对象
     * @return
     */
    @Override
    public byte[] serialize(Object obj) {
        // 得到该类的 Class 类模板
        Class<?> clazz = obj.getClass();
        // 通过 Class类模板获取 Schema 对象模式结构
        Schema schema = RuntimeSchema.getSchema(clazz);
        byte[] bytes;
        try {
            // 通过该对象，对象的结构以及缓冲区得到序列化数组
            bytes = ProtostuffIOUtil.toByteArray(obj, schema, BUFFER);
        } finally {
            BUFFER.clear();
        }
        return bytes;
    }

    /**
     * 反序列化方法
     * @param bytes 序列化后的字节数组
     * @param clazz 目标类
     * @param <T>
     * @return
     */
    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) {
        // 通过 Class 类模板获取 Schema 结构
        Schema<T> schema = RuntimeSchema.getSchema(clazz);
        T obj = schema.newMessage();
        // 然后通过结构和byte 数组获取对应对象
        ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
        return obj;
    }
}
